Skip to content

Introduce CommunityToolkit.VectorData.CosmosNoSql#21

Merged
adamsitnik merged 9 commits into
CommunityToolkit:mainfrom
adamsitnik:copilot/introduce-communitytoolkit-vector-data-cosmos
Jul 8, 2026
Merged

Introduce CommunityToolkit.VectorData.CosmosNoSql#21
adamsitnik merged 9 commits into
CommunityToolkit:mainfrom
adamsitnik:copilot/introduce-communitytoolkit-vector-data-cosmos

Conversation

@adamsitnik

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI and others added 7 commits July 2, 2026 16:26
Port Cosmos DB NoSQL MEVD provider from
roji/azure-cosmos-dotnet-v3@bc9919f5 into this repository.

- Source in MEVD/src/Cosmos with CommunityToolkit.VectorData.Cosmos namespace
- Unit tests in MEVD/test/Cosmos.UnitTests (xunit)
- Conformance tests in MEVD/test/Cosmos.ConformanceTests
- .NET Foundation copyright headers
- Add Microsoft.Azure.Cosmos 3.61.0 to Directory.Packages.props
- Update MEVD.slnf and CommunityToolkit.AI.slnx
…lator

- Add Testcontainers.CosmosDb package reference
- Rewrite CosmosNoSqlTestStore to use CosmosDbContainer with vnext-latest image
- Add CosmosNoSqlTestEnvironment for external connection string support
- Fix indexing policy path from '/' to '/*' for vNext compatibility
- Replace SELECT VALUE(c.id) with SELECT c.id + ContainerIdResult class
- Change DefaultIndexKind to DiskAnn (only type supported by vNext)
- Override SearchAsync_with_Skip (OFFSET not supported with DiskANN)
- Use thread-safe initialization with SemaphoreSlim
- move test classes into separate files
- disable failing tests
@adamsitnik
adamsitnik requested a review from Copilot July 7, 2026 17:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new Azure Cosmos DB for NoSQL provider implementation for Microsoft.Extensions.VectorData under CommunityToolkit.VectorData.Cosmos, along with unit + conformance test projects and solution/package wiring to build and validate it within the MEVD repo.

Changes:

  • Added the CommunityToolkit.VectorData.Cosmos provider (vector store, collections, mapping, filter translation, DI extensions, options, and supporting utilities).
  • Added Cosmos-specific unit tests and conformance tests (including Testcontainers-based emulator support).
  • Wired the new projects into solution filters/solution and added required package versions (Cosmos SDK + Testcontainers.CosmosDb).

Reviewed changes

Copilot reviewed 46 out of 46 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
MEVD/test/Cosmos.UnitTests/CosmosNoSqlOptionsTests.cs Adds unit tests for configuring Cosmos NoSQL options objects.
MEVD/test/Cosmos.UnitTests/Cosmos.UnitTests.csproj New unit test project for the Cosmos provider.
MEVD/test/Cosmos.ConformanceTests/Support/CosmosNoSqlTestStore.cs Test store bootstrapping Cosmos emulator / connection, and collection creation helpers.
MEVD/test/Cosmos.ConformanceTests/Support/CosmosNoSqlTestEnvironment.cs Loads Cosmos test connection settings from JSON/environment.
MEVD/test/Cosmos.ConformanceTests/Support/CosmosNoSqlFixture.cs Provides a shared fixture for Cosmos conformance tests.
MEVD/test/Cosmos.ConformanceTests/Support/CosmosNoSqlConformanceTestHelpers.cs Helper to adjust vector storage name casing for Cosmos behaviors.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlTestSuiteImplementationTests.cs Declares Cosmos conformance suite implementation and ignored bases.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlNoVectorModelTests.cs Cosmos conformance tests for “no vector” record model scenario.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlNoDataModelTests.cs Cosmos conformance tests for “no data” record model scenario.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlMultiVectorModelTests.cs Cosmos conformance tests for multi-vector record models.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlKeyTypeTests.cs Cosmos conformance tests for supported key types.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlIndexKindTests.cs Cosmos conformance tests for index kind behaviors/limitations.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlHybridSearchTests.cs Cosmos hybrid search conformance tests (currently disabled/internal due to emulator limits).
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlFilterTests.cs Cosmos filter conformance tests (currently disabled/internal due to emulator limits).
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlEmbeddingTypeTests.cs Cosmos conformance tests for embedding vector types and schema generation.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlEmbeddingGenerationTests.cs Cosmos conformance tests for embedding generation + DI registration paths.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlDynamicModelTests.cs Cosmos conformance tests for dynamic (dictionary-based) models.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlDistanceFunctionTests.cs Cosmos conformance tests for supported/unsupported distance functions.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlDependencyInjectionTests.cs Cosmos conformance tests for DI registration of vector store/collections.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlDataTypeTests.cs Cosmos conformance tests for supported default data types.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlCollectionManagementTests.cs Cosmos conformance tests for collection lifecycle management.
MEVD/test/Cosmos.ConformanceTests/CosmosNoSqlBasicModelTests.cs Cosmos conformance tests for basic record models and query behaviors.
MEVD/test/Cosmos.ConformanceTests/Cosmos.ConformanceTests.csproj New conformance test project for Cosmos provider.
MEVD/src/Cosmos/README.md Adds package README with install + usage + DI snippets.
MEVD/src/Cosmos/ICosmosNoSQLMapper.cs Defines internal mapping contract between data model and Cosmos JSON model.
MEVD/src/Cosmos/ErrorHandlingFeedIterator.cs Wraps Cosmos FeedIterator to route exceptions through vector-store error handling.
MEVD/src/Cosmos/CosmosNoSqlVectorStoreOptions.cs Adds vector store options (serializer options + embedding generator).
MEVD/src/Cosmos/CosmosNoSqlVectorStore.cs Implements Cosmos-backed VectorStore (collections, metadata, listing/deletion helpers).
MEVD/src/Cosmos/CosmosNoSqlServiceCollectionExtensions.cs Adds DI registration extensions for vector store and collections (keyed + non-keyed).
MEVD/src/Cosmos/CosmosNoSqlModelBuilder.cs Builds collection models and validates supported key/data/vector property types.
MEVD/src/Cosmos/CosmosNoSqlMapper.cs Maps typed records to/from Cosmos JSON, including embedding serialization behavior.
MEVD/src/Cosmos/CosmosNoSqlKey.cs Introduces composite key type (document id + partition key).
MEVD/src/Cosmos/CosmosNoSqlFilterTranslator.cs Translates filter expressions into Cosmos SQL WHERE clauses with parameters.
MEVD/src/Cosmos/CosmosNoSqlDynamicMapper.cs Maps dynamic Dictionary<string, object?> records to/from Cosmos JSON.
MEVD/src/Cosmos/CosmosNoSqlDynamicCollection.cs Provides a dynamic collection wrapper specialized for dictionary records.
MEVD/src/Cosmos/CosmosNoSqlConstants.cs Centralizes Cosmos provider constants (system name, id key, alias).
MEVD/src/Cosmos/CosmosNoSqlCollectionQueryBuilder.cs Builds Cosmos SQL queries for vector + hybrid search and filtered retrieval.
MEVD/src/Cosmos/CosmosNoSqlCollectionOptions.cs Adds collection options (partition key properties, indexing mode, automatic indexing).
MEVD/src/Cosmos/CosmosNoSqlCollection.cs Implements Cosmos-backed VectorStoreCollection with CRUD/search, indexing, PK building.
MEVD/src/Cosmos/Cosmos.csproj Adds the new Cosmos provider package project (multi-targeted).
MEVD/src/Cosmos/ClientWrapper.cs Manages CosmosClient ownership and reference-counted sharing/disposal.
MEVD/src/Cosmos/ByteArrayJsonConverter.cs Adds JSON converters to serialize byte vectors as numeric arrays (Cosmos requirement).
MEVD/src/Cosmos/AssemblyInfo.cs Adds assembly-level license header file.
MEVD/MEVD.slnf Adds Cosmos projects to the MEVD solution filter.
Directory.Packages.props Adds package versions for Cosmos SDK and Testcontainers.CosmosDb.
CommunityToolkit.AI.slnx Adds Cosmos projects to the main solution structure.

Comment thread MEVD/src/CosmosNoSql/CosmosNoSqlServiceCollectionExtensions.cs
Comment thread MEVD/src/CosmosNoSql/CosmosNoSqlServiceCollectionExtensions.cs
Comment thread MEVD/src/CosmosNoSql/CosmosNoSqlServiceCollectionExtensions.cs
Comment thread MEVD/src/CosmosNoSql/CosmosNoSqlServiceCollectionExtensions.cs
Comment thread MEVD/src/CosmosNoSql/CosmosNoSqlModelBuilder.cs
Comment thread MEVD/src/CosmosNoSql/CosmosNoSqlDynamicMapper.cs
Comment thread MEVD/src/CosmosNoSql/CosmosNoSqlCollection.cs
Comment thread MEVD/test/CosmosNoSql.ConformanceTests/CosmosNoSqlDependencyInjectionTests.cs Outdated
Comment thread MEVD/test/CosmosNoSql.ConformanceTests/CosmosNoSqlFilterTests.cs
@adamsitnik
adamsitnik requested a review from Copilot July 7, 2026 17:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 46 out of 46 changed files in this pull request and generated 10 comments.

Comment thread MEVD/src/CosmosNoSql/CosmosNoSqlModelBuilder.cs Outdated
Comment on lines +137 to +142
// Embedding<T> is stored as a simple JSON array, so convert it to the expected object shape for deserialization
if (vectorProperty.Type == typeof(Embedding<float>)
|| vectorProperty.Type == typeof(Embedding<byte>)
|| vectorProperty.Type == typeof(Embedding<sbyte>))
{
storageModel[vectorProperty.StorageName] = new JsonObject
Comment thread MEVD/src/CosmosNoSql/CosmosNoSqlServiceCollectionExtensions.cs
Comment thread MEVD/src/CosmosNoSql/CosmosNoSqlServiceCollectionExtensions.cs
Comment thread MEVD/src/CosmosNoSql/CosmosNoSqlServiceCollectionExtensions.cs
Comment thread MEVD/src/CosmosNoSql/CosmosNoSqlServiceCollectionExtensions.cs
Comment thread MEVD/test/CosmosNoSql.ConformanceTests/CosmosNoSqlDependencyInjectionTests.cs Outdated
Comment thread MEVD/test/CosmosNoSql.ConformanceTests/CosmosNoSqlFilterTests.cs Outdated
Comment thread MEVD/test/CosmosNoSql.ConformanceTests/CosmosNoSqlMultiVectorModelTests.cs Outdated

@adamsitnik adamsitnik left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, ready for review

Comment on lines +10 to +12
private readonly Lazy<CosmosNoSqlTestStore> _store = new(() => new CosmosNoSqlTestStore(nameof(CosmosNoSqlFixture)));

public override TestStore TestStore => _store.Value;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To other reviewers: typically VectorStoreFixture.TestStore returns a static, cached singleton of TestStore. The Cosmos emulator struggles today if we run multiple queries against it, even sequentially. What works best is if we have a dedicated Database for every test class. So this and other fixtures create their own CosmosNoSqlTestStore instances.

Thanks to the fact that each of them uses a different container instance, we can run tests in parallel and reduce the time it takes to run them from 100s to 20s (at least on my machine)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

{
public override Task SearchAsync_with_Skip()
{
// The vNext emulator's DiskANN index does not support OFFSET in vector search.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To other code reviewers: as soon as dotnet/extensions migrates to xUnit 3 (dotnet/extensions#7607), we are going to be able to use Assert.Skip here and have a "proper" way to skip the tests

namespace CosmosNoSql.ConformanceTests;

// The type is internal to disable the tests due to emulator limitations
internal sealed class CosmosNoSqlDataTypeTests(CosmosNoSqlDataTypeTests.Fixture fixture)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to other code reviewers: this is a workaround. The emulator simply can't handle it today, so instead of removing/commenting out the code I've marked this and two other classes as internal. I intend to log dedicated emulator bugs once this repo becomes public.

public override async Task<bool> CollectionExistsAsync(CancellationToken cancellationToken = default)
{
const string OperationName = "ListCollectionNamesAsync";
const string Query = "SELECT c.id FROM c WHERE c.id = @collectionName";

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To other code reviewers: this is a product change in order to get tests passing on emulator. The change was introduced by copilot in 2476214

What it did was more or less:

-"SELECT VALUE(c.id) FROM c WHERE c.id = @collectionName"
+"SELECT c.id FROM c WHERE c.id = @collectionName"

I've verified and the tests are not going to pass without it. It may be just an emulator limitation (https://learn.microsoft.com/en-us/azure/cosmos-db/emulator-linux).

@roji PTAL

@roji roji Jul 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, that's slightly uglier but if CollectionExistsAsync continues to work reliably, it should be fine. Though it's a super, super basic query form - very odd that it doesn't work. If you have a moment to actually try it (the emulator has a local web interface you can run queries on) that would confirm, because this is slightly fishy.

I'd suggest reporting with a minimal repro on https://github.com/Azure/azure-cosmos-db-emulator-docker, as I'm 99% sure this was working on the Windows emulator.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created #23, will start reporting as soon as I've some free cycles. I wanted to do it ASAP but currently I have hard time creating Cosmos DB instance via Azure Portal (to verify my repros)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be easier to just use the Windows emulator locally for that, in case Azure gives you trouble.

}

// Adding special mandatory indexing path.
indexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To other code reviewers: this is another product change in order to get tests passing on emulator. The change was introduced by copilot in 2476214

What it did was more or less:

-indexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/" });
+indexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });

I've verified and the tests are not going to pass without it. It may be just an emulator limitation (https://learn.microsoft.com/en-us/azure/cosmos-db/emulator-linux).

@roji PTAL

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm no expert in Cosmos indexing policies, but this does look a bit odd... If the docs say the two are the same then no problem of course, but I'd signal this to the Linux emulator folks as well (everything was working with the Windows one).

/// <inheritdoc />
public override async IAsyncEnumerable<string> ListCollectionNamesAsync([EnumeratorCancellation] CancellationToken cancellationToken = default)
{
const string Query = "SELECT c.id FROM c";

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To other code reviewers: this is another product change in order to get tests passing on emulator. The change was introduced by copilot in 2476214

What it did was more or less:

-"SELECT VALUE(c.id) FROM c"
+"SELECT c.id FROM c"

I've verified and the tests are not going to pass without it. It may be just an emulator limitation (https://learn.microsoft.com/en-us/azure/cosmos-db/emulator-linux).

@roji PTAL

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the same as #21 (comment)

@adamsitnik adamsitnik changed the title Introduce CommunityToolkit.VectorData.Cosmos Introduce CommunityToolkit.VectorData.CosmosNoSql Jul 7, 2026
@adamsitnik
adamsitnik requested review from roji and westey-m July 7, 2026 18:29

@roji roji left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rubber-stamping as this is essentially just moving of existing code.

@adamsitnik
adamsitnik merged commit 529e9fe into CommunityToolkit:main Jul 8, 2026
105 of 107 checks passed
@adamsitnik
adamsitnik deleted the copilot/introduce-communitytoolkit-vector-data-cosmos branch July 8, 2026 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants